﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Weazel.Gezel.Model
{
  /// <summary>
  /// Serves as a base class for Datapaths and IpBlocks
  /// </summary>
	public abstract class Block : AbstractEntity<object> 
	{
		/// <summary>
		/// The collection of input ports hashed on their
		/// local names.
		/// </summary>
		internal readonly Dictionary<string, InPort> inPorts;
		public Dictionary<string, InPort> InPorts
		{
			get
			{			
        return inPorts;
			}
		}

		/// <summary>
		/// The collection of output ports hashed on their
		/// local names.
		/// </summary>
		internal readonly Dictionary<string, OutPort> outPorts;
		public Dictionary<string, OutPort> OutPorts
		{
			get
			{
				return outPorts;
			}
		}

		/// <summary>
		/// Gezel systems connects ports of its entities
		/// (datapaths, stimuli and ipblocks) by using
		/// position based bindings, therefore it should
		/// be possible to lookup a port based on its
		/// position in the port list declaration
		/// </summary>
		/// <param name="position"></param>
		/// <returns></returns>
		public Port GetPortAtPosition(int position)
		{
			foreach (InPort ip in inPorts.Values)
				if (ip.DeclarationPosition == position)
					return ip;

			foreach (OutPort op in outPorts.Values)
				if (op.DeclarationPosition == position)
					return op;

			return null; // port was not found
		}

		/// <summary>
		/// Given the local name of a port this method
		/// returns the actual object - if it exists.
		/// </summary>
		/// <param name="name">local name of port to get</param>
		/// <returns></returns>
		public Port GetPortByLocalName(string name)
		{
			foreach (InPort port in InPorts.Values)
				if (port.LocalName == name)
					return port;

			foreach (OutPort port in outPorts.Values)
				if (port.LocalName == name)
					return port;

			return null;
		}

		public Block(object parent, string name)
			: base(parent, name)
		{
      inPorts = new Dictionary<string, InPort>();
      outPorts = new Dictionary<string, OutPort>();
		}

		public Block(object parent, string name, Position startPosition, Position endPosition)
			: base(parent, name, startPosition, endPosition)
		{
			inPorts = new Dictionary<string, InPort>();
			outPorts = new Dictionary<string, OutPort>();
		}
	}
}
